{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "7a4b75bb-d60a-41e3-abca-1ca0f0bf1201",
   "metadata": {},
   "source": [
    "<a href=\"https://colab.research.google.com/github/meta-llama/llama-recipes/blob/main/recipes/quickstart/agents/dlai/AI_Agentic_Design_Patterns_with_AutoGen_L4_Tool_Use_and_Conversational_Chess.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51581f90-911f-46ef-82dd-f3ca9c1d4b96",
   "metadata": {},
   "source": [
    "This notebook ports the DeepLearning.AI short course [AI Agentic Design Patterns with AutoGen Lesson 4 Tool Use and Conversational Chess](https://learn.deeplearning.ai/courses/ai-agentic-design-patterns-with-autogen/lesson/5/tool-use-and-conversational-chess) to using Llama 3. \n",
    "\n",
    "You should take the course before or after going through this notebook to have a deeper understanding."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f9824ea5-3791-4638-a09d-43eb2c906d79",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "!pip install chess\n",
    "!pip install pyautogen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a082a6dc-ceb1-4a3e-b3ae-afcb835de6da",
   "metadata": {},
   "outputs": [],
   "source": [
    "import chess\n",
    "import chess.svg\n",
    "from typing_extensions import Annotated"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fbcdd9ea-f589-463d-a306-3fb3fcde770c",
   "metadata": {},
   "outputs": [],
   "source": [
    "board = chess.Board()\n",
    "\n",
    "made_move = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9d27858c-4a0b-40f6-bd58-01b19c33ab38",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_legal_moves(\n",
    "    \n",
    ") -> Annotated[str, \"A list of legal moves in UCI format\"]:\n",
    "    return \"Possible moves are: \" + \",\".join(\n",
    "        [str(move) for move in board.legal_moves]\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "67742daa-9d9a-46b3-9466-beb96d535334",
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import SVG\n",
    "\n",
    "def make_move(\n",
    "    move: Annotated[str, \"A move in UCI format.\"]\n",
    ") -> Annotated[str, \"Result of the move.\"]:\n",
    "    move = chess.Move.from_uci(move)\n",
    "    board.push_uci(str(move))\n",
    "    global made_move\n",
    "    made_move = True\n",
    "    \n",
    "    svg_str = chess.svg.board(\n",
    "            board,\n",
    "            arrows=[(move.from_square, move.to_square)],\n",
    "            fill={move.from_square: \"gray\"},\n",
    "            size=200\n",
    "        )\n",
    "    display(\n",
    "        SVG(data=svg_str)\n",
    "    )\n",
    "    \n",
    "    # Get the piece name.\n",
    "    piece = board.piece_at(move.to_square)\n",
    "    piece_symbol = piece.unicode_symbol()\n",
    "    piece_name = (\n",
    "        chess.piece_name(piece.piece_type).capitalize()\n",
    "        if piece_symbol.isupper()\n",
    "        else chess.piece_name(piece.piece_type)\n",
    "    )\n",
    "    return f\"Moved {piece_name} ({piece_symbol}) from \"\\\n",
    "    f\"{chess.SQUARE_NAMES[move.from_square]} to \"\\\n",
    "    f\"{chess.SQUARE_NAMES[move.to_square]}.\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e84508c0-0465-4be8-a97b-2e702265bcfb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# base url from https://console.groq.com/docs/openai\n",
    "config_list = [\n",
    "    {\n",
    "        \"model\": \"llama3-70b-8192\",\n",
    "        \"base_url\": \"https://api.groq.com/openai/v1\",\n",
    "        'api_key': 'your_groq_api_key', # get a free key at https://console.groq.com/keys\n",
    "    },\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "86dbb782-61f0-4b61-aab5-41fd12c26f51",
   "metadata": {},
   "outputs": [],
   "source": [
    "from autogen import ConversableAgent\n",
    "\n",
    "# Player white agent\n",
    "player_white = ConversableAgent(\n",
    "    name=\"Player White\",\n",
    "    system_message=\"You are a chess player and you play as white. \"\n",
    "    \"First call get_legal_moves(), to get a list of legal moves in UCI format. \"\n",
    "    \"Then call make_move(move) to make a move. Finally, tell the proxy what you have moved and ask the black to move\", # added \"Finally...\" to make the agents work\n",
    "    llm_config={\"config_list\": config_list,\n",
    "                \"temperature\": 0,\n",
    "               },\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1c57411c-183a-44ea-95ab-33c0e97feb74",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Player black agent\n",
    "player_black = ConversableAgent(\n",
    "    name=\"Player Black\",\n",
    "    system_message=\"You are a chess player and you play as black. \"\n",
    "    \"First call get_legal_moves(), to get a list of legal moves in UCI format. \"\n",
    "    \"Then call make_move(move) to make a move. Finally, tell the proxy what you have moved and ask the white to move\", # added \"Finally...\" to make the agents work\n",
    "    llm_config={\"config_list\": config_list,\n",
    "                \"temperature\": 0,\n",
    "               },)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "60e5cb2d-4273-45a9-af40-0ffb1ada0009",
   "metadata": {},
   "outputs": [],
   "source": [
    "def check_made_move(msg):\n",
    "    global made_move\n",
    "    if made_move:\n",
    "        made_move = False\n",
    "        return True\n",
    "    else:\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be4c7b55-9d50-4aa8-ae4b-3b959ffbb298",
   "metadata": {},
   "outputs": [],
   "source": [
    "board_proxy = ConversableAgent(\n",
    "    name=\"Board Proxy\",\n",
    "    llm_config=False,\n",
    "    is_termination_msg=check_made_move,\n",
    "    default_auto_reply=\"Please make a move.\",\n",
    "    human_input_mode=\"NEVER\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e122875c-8bff-4212-8a1b-5f91d253fdd7",
   "metadata": {},
   "outputs": [],
   "source": [
    "from autogen import register_function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "20edcb8c-5b7b-438e-b476-1cb16d14ef62",
   "metadata": {},
   "outputs": [],
   "source": [
    "for caller in [player_white, player_black]:\n",
    "    register_function(\n",
    "        get_legal_moves,\n",
    "        caller=caller,\n",
    "        executor=board_proxy,\n",
    "        name=\"get_legal_moves\",\n",
    "        description=\"Call this tool to get all legal moves in UCI format.\",\n",
    "    )\n",
    "    \n",
    "    register_function(\n",
    "        make_move,\n",
    "        caller=caller,\n",
    "        executor=board_proxy,\n",
    "        name=\"make_move\",\n",
    "        description=\"Call this tool to make a move.\",\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b254ea02-0a81-4e9f-91fa-788dead9ffb8",
   "metadata": {},
   "outputs": [],
   "source": [
    "player_black.llm_config[\"tools\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3715f56c-8ab8-4563-8f00-233beb3959b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "player_white.register_nested_chats(\n",
    "    trigger=player_black,\n",
    "    chat_queue=[\n",
    "        {\n",
    "            \"sender\": board_proxy,\n",
    "            \"recipient\": player_white,\n",
    "            \"summary_method\": \"last_msg\",\n",
    "        }\n",
    "    ],\n",
    ")\n",
    "\n",
    "player_black.register_nested_chats(\n",
    "    trigger=player_white,\n",
    "    chat_queue=[\n",
    "        {\n",
    "            \"sender\": board_proxy,\n",
    "            \"recipient\": player_black,\n",
    "            \"summary_method\": \"last_msg\",\n",
    "        }\n",
    "    ],\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eda4f544-ab4c-4e9e-bceb-f93ad57c4026",
   "metadata": {},
   "outputs": [],
   "source": [
    "board = chess.Board()\n",
    "\n",
    "chat_result = player_black.initiate_chat(\n",
    "    player_white,\n",
    "    message=\"Let's play chess! Your move.\",\n",
    "    max_turns=3,\n",
    ")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
